/*
 * @Description: 地图页面
 * @Author: Yong
 * @Date: 2021-09-24 21:32:54
 * @LastEditTime: 2021-09-26 11:23:39
 */
import React from "react"
import { Link } from "react-router-dom"
import { BASE_URL } from '../../utils/url'
import NavHeader from "../../components/NavHeader"
import HouseItem from "../../components/HouseItem"
import { getAreaMap } from "../../apis/map"
import { getHouseList } from "../../apis/house"
import styles from './index.module.css'
// 解决脚手架中全局变量访问的问题
const BMapGL = window.BMapGL
// 覆盖物样式
const labelStyle = {
    cursor: 'pointer',
    border: '0px solid rgb(255, 0, 0)',
    padding: '0px',
    whiteSpace: 'nowrap',
    fontSize: '12px',
    color: 'rgb(255, 255, 255)',
    textAlign: 'center'
}

export default class News extends React.Component {

    state = {
        houseList: [],    // 房源列表
        isShowList: false, // 是否展示房源列表
        map: null
    }

    componentDidMount () {
        this.initMap()

    }

    initMap () {
        // 获取当前缓存的定位城市和id
        const { label: cityName, value: id } = JSON.parse(localStorage.getItem('hkzf_city'))
        const map = new BMapGL.Map('container')
        this.map = map
        // 创建地址解析器实例
        const myGeo = new BMapGL.Geocoder()
        // 将地址解析结果显示在地图上，并调整地图视野
        myGeo.getPoint(cityName, async point => {
            if (point) {
                //  初始化地图 - 地图展示级别11
                map.centerAndZoom(point, 11)

                // 添加常用控件(比例尺、缩放)
                map.addControl(new BMapGL.NavigationControl())
                map.addControl(new BMapGL.ScaleControl())

                // 渲染地图覆盖物
                this.renderOverlays(id)
            }
        }, cityName)

        // 给地图绑定移动事件
        map.addEventListener('movestart', (e) => {
            console.log(e)
            if (this.state.isShowList) {
                this.setState({
                    isShowList: false
                })
            }
        })
    }

    /**
     * 渲染地图覆盖物
     * @param {*} id 根据ID获取房源数据
     */
    async renderOverlays (id) {
        const areaMapInfoList = await getAreaMap(id)
        // 获取当前地图级别和类型
        const { nextZoom, type } = this.getTypeAndZoom()
        // 每个房源数据都创建覆盖物
        areaMapInfoList.forEach(item => {
            this.createOverlays(item, nextZoom, type)
        })
    }

    // 计算要绘制的覆盖物类型和下一个缩放级别
    // 区   -> 11 ，范围：>=10 <12
    // 镇   -> 13 ，范围：>=12 <14
    // 小区 -> 15 ，范围：>=14 <16
    getTypeAndZoom () {
        // 调用地图的 getZoom() 方法，来获取当前缩放级别
        const zoom = this.map.getZoom()
        let nextZoom, type

        // console.log('当前地图缩放级别：', zoom)
        if (zoom >= 10 && zoom < 12) {
            // 区
            // 下一个缩放级别
            nextZoom = 13
            // circle 表示绘制圆形覆盖物（区、镇）
            type = 'circle'
        } else if (zoom >= 12 && zoom < 14) {
            // 镇
            nextZoom = 15
            type = 'circle'
        } else if (zoom >= 14 && zoom < 16) {
            // 小区
            type = 'rect'
        }

        return {
            nextZoom,
            type
        }
    }

    /**
     * 创建覆盖物
     * @param {*} areaMapInfo 房源信息
     * @param {*} zoom        地图展示级别
     * @param {*} type        房源类型 - 区镇/小区
     */
    createOverlays (areaMapInfo, zoom, type) {
        const { coord: { longitude, latitude }, label: areaName, count, value: id } = areaMapInfo
        // 创建坐标对象
        const areaPoint = new BMapGL.Point(longitude, latitude)
        // 创建覆盖物
        if (type === 'circle') {
            this.createCircle(areaPoint, areaName, count, id, zoom)
        } else {
            this.createRect(areaPoint, areaName, count, id)
        }
    }

    // 创建区镇覆盖物
    createCircle (point, areaName, count, id, zoom) {
        // 创建覆盖物
        const label = new BMapGL.Label('', {
            position: point,
            offset: new BMapGL.Size(-35, -35), // 坐标偏移量 - 对齐中心点
        })

        // 给 label 对象添加一个唯一标识
        label.id = id

        // 设置房源覆盖物内容
        label.setContent(`
            <div class="${styles.bubble}">
            <p class="${styles.name}">${areaName}</p>
            <p>${count}套</p>
            </div>
        `)

        // 设置样式
        label.setStyle(labelStyle)
        // 添加单击事件
        label.addEventListener('click', (e) => {
            console.log(e)
            // 调用 renderOverlays 方法，获取该区域下的房源数据
            this.renderOverlays(id)

            // 放大地图，以当前点击的覆盖物为中心放大地图
            this.map.centerAndZoom(point, zoom)

            // 解决清除覆盖物时，百度地图API的JS文件自身报错的问题
            setTimeout(() => {
                // 清除当前覆盖物信息
                this.map.clearOverlays()
            }, 0)
        })

        // 添加覆盖物到地图中
        this.map.addOverlay(label)
    }

    // 创建小区覆盖物
    createRect (point, houseName, count, id) {
        // 创建覆盖物
        const label = new BMapGL.Label('', {
            position: point,
            offset: new BMapGL.Size(-50, -28)
        })

        // 给 label 对象添加一个唯一标识
        label.id = id

        // 设置房源覆盖物内容
        label.setContent(`
            <div class="${styles.rect}">
                <span class="${styles.housename}">${houseName}</span>
                <span class="${styles.housenum}">${count}套</span>
                <i class="${styles.arrow}"></i>
            </div>
        `)

        // 设置样式
        label.setStyle(labelStyle)

        // 添加单击事件
        this.map.addEventListener('click', e => {
            // 获取并渲染房源数据
            this.getHouseList(id)
            // 获取当前被点击项
            // const target = e.changedTouches[0]

            this.map.panBy(
                window.innerWidth / 2 - 50,
                (window.innerHeight - 330) / 2 - 100
            )
        })

        // 添加覆盖物到地图中
        this.map.addOverlay(label)
    }

    // 获取小区房源数据
    async getHouseList (id) {
        const { list } = await getHouseList({ cityId: id })
        this.setState({ houseList: list, isShowList: true })
    }

    // 渲染房屋列表的方法
    renderHousesList = () => {
        return this.state.houseList.map(item => (
            <HouseItem
                onClick={() => this.props.history.push(`/detail/${item.houseCode}`)}
                key={item.houseCode}
                src={BASE_URL + item.houseImg}
                title={item.title}
                desc={item.desc}
                tags={item.tags}
                price={item.price}
            />
        ))
    }

    render () {
        return (
            <div className={styles.map}>
                {/* 顶部导航 */}
                <NavHeader>地图找房</NavHeader>
                {/* 地图容器 */}
                <div id="container" className={styles.container}></div>
                {/* 房源列表 */}
                {/* 添加 styles.show 展示房屋列表 */}
                <div className={[styles.houseList, this.state.isShowList ? styles.show : ''].join(' ')}>
                    <div className={styles.titleWrap}>
                        <h1 className={styles.listTitle}>房屋列表</h1>
                        <Link className={styles.titleMore} to="/home/list">
                            更多房源
                        </Link>
                    </div>

                    <div className={styles.houseItems}>
                        {/* 房屋结构 */}
                        {this.renderHousesList()}
                    </div>
                </div>
            </div>
        )
    }
}